import re
from itertools import izip
from errors import *
from util import *
from cardsharp.errors import RuleError as CSRuleError
def _code_unknown(ruleset, row, unknown):
for v in ruleset.vars:
#do not code variables listed in skip unknown
if v[0] not in ruleset.skip_unknown:
#only overwrite if variable name is in overwrite rule
if v[0] not in ruleset.overwrite and row[v[0]] is not None:
continue
row[v[0]] = unknown[v[0]]
[docs]class SentenceRules(object):
def __init__(self, log):
self.log = log
self.unknown = {'cnf' : 9, 'trt' : 9, 'cmsrv' : 9999.99, 'oth' : None, 'pjp':99}
self.na = {'cnf' : 8}
for var in ('incmax', 'incmin', 'suspmax', 'suspmin', 'prb', 'fineamt', 'suspfine', 'rst', 'costs'):
self.unknown[var] = 99999999.99
if var in ('incmax', 'incmin', 'suspmax', 'suspmin', 'prb'):
self.na[var] = 99899899.88
self.missing = self.unknown
[docs] def convert_sentences(self, row, ruleset, **kw):
#TODO break this into many different functions tom improve performance?
'''Tries to convert sentences by finding key in ruleset. If key not found then codes unknown.
@param row: The row to assign values to
@param ruleset: The ruleset which stores the key, value rule mappings to convert a given key into sentence variables
@param skip_unknown: A list of variables which should not be coded during unknown coding.
@return: Returns the key that was passed in on key param. If remove_key is true will remove the key that was matched on from the string
'''
remove_key = ruleset.remove_key
#if null_predicate defined check to make sure all null_predicate variables are None
if len(ruleset.null_predicate) != 0:
for v in ruleset.null_predicate:
if row[v] is not None:
if ruleset.metadata.force_unknown:
_code_unknown(ruleset, row, self.unknown)
return None
#if overwrite not set then check to make sure at least one null value before running crosswalk
if len(ruleset.overwrite) == 0:
for v in ruleset.null_predicate:
if row[v] is None:
break
return None
#TODO need to make this work if we have multiple key values
#allows convert_key to be passed in
_row = {ruleset.metadata.key_meta[0].name:kw.get('convert_key')} if kw.get('convert_key') is not None else row
key = ruleset.metadata.get_key(_row)
convert_key = '|'.join([k if k else '' for k in key])
try:
#if key_predicate text is not in key code as unknown
if ruleset.key_predicate:
if not ruleset.key_predicate.search(convert_key):
_code_unknown(ruleset, row, self.unknown)
return convert_key
#construct the keyword arguments
kw_args = {'remove':remove_key,
'transform_results':ruleset.transform_results}
#if more than one vars than we split
if ruleset.vars > 1:
kw_args['split'] = '|'
#if transform_results is True than pass in the row and ruleset.varaible data to the convert method
if ruleset.transform_results:
kw_args['row'] = row
#try to match a rule in the ruleset to convert_key
result = ruleset.convert(convert_key, **kw_args)
if isinstance(result, tuple):
snt_vars, key_str = result
convert_key = key_as_str(convert_key.replace(key_str, ''))
else:
#make sure snt_vars is a list
snt_vars = result if ruleset.vars > 1 else [result]
for k,v in izip(ruleset.vars, snt_vars):
#only overwrite if overwrite is set to True
if k[0] not in ruleset.overwrite and row[k[0]] is not None:
continue
try:
row[k[0]] = v
except CSRuleError as e:
#if a rule error occurs
row[k[0]] = -9
self.log.write('snttext_errors', [row['id'], row['rapstatex'], convert_key, e])
#all rules in ruleset do not find a match on convert_key, code as unknown
except ConvertError as e:
_code_unknown(ruleset, row, self.unknown)
if ruleset.key_predicate:
self.log.write('snttext', [row['id'], row['rapstatex'], convert_key,
"convert_key not found in xwalk, but convert_key had key_predicate: %s." % ruleset.key_predicate.pattern])
except RuleError as e:
self.log.write('snttext_rule_errors', [row['id'], row['rapstatex'], e])
return convert_key
[docs] def recode_inc(self, row):
if row['incmax'] != 99999999.99 and row['incmin'] == 99999999.99:
row['incmin'] == 99899899.88
elif row['incmin'] != 99999999.99 and row['incmax'] == 99999999.99:
row['incmax'] == 99799799.77
return